/**
* @package Scribble
*/
$(document).ready(function() {
	MediaBrowser.init();
});

var MediaBrowser = {

	/**
	* Cache of loaded server data.
	*
	* @var object
	*/
	cache: {},

	/**
	* Configuration store.
	*
	* @var object
	*/
	config: {
		callback: null,
		data: '',
		path: '',
		smax: 1,
		stype: '*',
		uploadPathPrefix: '',
		view: 'list'
	},

	/**
	* URL from which media asset lists will be loaded.
	*
	* @var string
	*/
	feedUrl: '',

	/**
	* Sends info about the chosen assets back to the opener via the callback
	* function. It does NOT close the popup - it leaves it up to the callback
	* function in case it wants to run validation checks prior to closing.
	*
	* @return void
	*/
	complete: function() {
		MediaBrowser.config.callback('complete', MediaBrowser, {
			selection: MediaBrowser.config.data
		});
	},

	/**
	* Initialise the view.
	*
	* @return void
	*/
	init: function() {

		// Grab configuration variables from "#config" hidden field which contains a
		// JSON encoded version of the config
		var configField = $('#config');
		if(configField.size()==0) {
			$('#view').html('<p>No configuration data has been specified. Cannot continue.</p>');
			return;
		}
		else {
			MediaBrowser.config = $.extend({}, MediaBrowser.config, $.evalJSON(configField.val()));
			$('#view').html('');
		}

		// Check callback has been defined
		var callback = top[MediaBrowser.config.callback] ? top[MediaBrowser.config.callback] : (
			window.opener && window.opener[MediaBrowser.config.callback] ? window.opener[MediaBrowser.config.callback] : null
		);
		if(callback===null) {
			$('#view').html('<p>The callback function is either undefined or does not exist. Cannot continue.</p>');
			return;
		}
		else {
			MediaBrowser.config.callback = callback;
		}

		// JSON-decode data
		if(MediaBrowser.config.data=='') {
			MediaBrowser.config.data = [];
		}
		else {
			MediaBrowser.config.data = $.evalJSON(MediaBrowser.config.data);
		}

		// Setup the feed url
		MediaBrowser.feedUrl = Buan.UrlCommand.createUrl('scribble', 'media-library', 'browser-widget', MediaBrowser.config);

		// Add handler to "backup" button
		$('#backup').click(function() {
			var path = MediaBrowser.config.path.replace(/\/[^\/]+$/, "");
			MediaBrowser.load(path);
			return false;
		});

		// View option handlers
		$('#view-thumbnails').click(function() {
			MediaBrowser.toggleLayout('thumbnails');
			return false;
		});
		$('#view-list').click(function() {
			MediaBrowser.toggleLayout('list');
			return false;
		});

		// "OK" button handler
		$('#btn-complete').click(MediaBrowser.complete);

		// Load initial path and render any existing selections
		MediaBrowser.load(MediaBrowser.config.path);
		MediaBrowser.renderSelection();
	},

	/**
	* Loads a list of media assets from the server, and caches result.
	* The response will include the following elements:
	* - A list of files/folders
	* - The full URL to the opened folder
	*
	* @param string Path to load (including upload folder prefix)
	* @return void
	*/
	load: function(path) {

		// Consult cache
		if(MediaBrowser.cache[path]) {
			MediaBrowser.renderView(MediaBrowser.cache[path]);
			return;
		}

		// Load indicators
		$('#url').attr('disabled', 'disabled').addClass('server-busy');
		$('#view').html('');

		// Request
		$.post(MediaBrowser.feedUrl, {method:'load', path:path}, function(feed) {

			// Check error code
			$('#url').attr('disabled', '').removeClass('server-busy');
			if(feed.errorCode!==0) {
				alert(feed.errorMessage+'[code: '+feed.errorCode+']');
				return;
			}

			// Cache and render view
			MediaBrowser.cache[path] = feed;
			MediaBrowser.renderView(feed);
		}, 'json');
	},

	removeFile: function(path) {
		var data = [];
		for(var i=0; i<MediaBrowser.config.data.length; i++) {
			var filePath = MediaBrowser.config.data[i];
			if(filePath!==path) {
				data.push(filePath);
			}
		}
		MediaBrowser.config.data = data;
		MediaBrowser.renderSelection();
	},

	/**
	* This handler is bound to the "click" event on all links in the selection
	* container.
	*
	* @return false
	*/
	removeSelectionLink: function() {

		// Remove file
		MediaBrowser.removeFile($(this).attr('href'));
		return false;
	},

	/**
	* Renders the list of selected assets.
	*
	* @return void
	*/
	renderSelection: function() {
		var container = $('#selection');
		var ul = $('<ul></ul>');
		for(var i=0; i<MediaBrowser.config.data.length; i++) {
			var filePath = MediaBrowser.config.data[i];
			var fileName = filePath.replace(/^.*\/([^\/]+)$/, "$1");
			var li = $('<li><a href="#"></a></li>');
			li.children('a').html(fileName).attr('href', filePath).click(MediaBrowser.removeSelectionLink);
			ul.append(li);
		}
		container.html('').append(ul);
	},

	/**
	* Render the view using the given data.
	*
	* @param object Data, as it appears in the cache
	* @return void
	*/
	renderView: function(data) {

		// URL path
		$('#url').val(data.url);
		MediaBrowser.config.path = data.url;

		// Show/hide "backup" button if we've opened a subfolder
		var re = new RegExp('^'+MediaBrowser.config.uploadPathPrefix.replace(/\//, '\\/'));
		var subpath = MediaBrowser.config.path.replace(re, '');
		$('#backup').toggle(subpath!='');

		// Render view according to view option
		$('#view').html('');
		if(MediaBrowser.config.view=='thumbnails') {
			MediaBrowser.renderViewThumbnails(data);
		}
		else {
			MediaBrowser.renderViewList(data);
		}
	},

	/**
	* Render assets as a list
	*
	* @param object Asset data
	* @return void
	*/
	renderViewList: function(data) {

		// Build table
		var table = $('<table><thead><tr><th class="col-icon">&#160;</th><th class="col-filename">Filename</th><th class="col-filesize">Size</th><th class="col-datemodified">Modified</th></tr></thead><tbody></tbody></table>');
		var tbody = table.children('tbody');

		for(var i in data.assets.folders) {
			var asset = data.assets.folders[i];
			var tr = $('<tr class="folder" rel="asset"><td class="col-icon">-</td><td class="col-filename"><a href=""></a></td><td class="col-filesize"></td><td class="col-datemodified"></td></tr>');
			tr.children('td.col-filename').children('a').attr('href', asset.url).html(asset.filename).click(MediaBrowser.selectAssetLink);
			tr.children('td.col-filesize').html('-');
			tr.children('td.col-datemodified').html(asset.datemodified);
			tbody.append(tr);
		}

		for(var i in data.assets.files) {
			var asset = data.assets.files[i];
			var tr = $('<tr class="file" rel="asset"><td class="col-icon">-</td><td class="col-filename"><a href=""></a></td><td class="col-filesize"></td><td class="col-datemodified"></td></tr>');
			tr.children('td.col-filename').children('a').attr('href', asset.url).html(asset.filename).click(MediaBrowser.selectAssetLink);
			tr.children('td.col-filesize').html(asset.filesize);
			tr.children('td.col-datemodified').html(asset.datemodified);
			tbody.append(tr);
		}

		$('#view').append(table);
	},

	/**
	* Render the assets as thumbnails.
	*
	* @param object Asset data
	* @return void
	*/
	renderViewThumbnails: function(data) {
		var view = $('#view');
		for(var i in data.assets.folders) {
			var asset = data.assets.folders[i];
			var thumb = $('<div class="thumbnail folder" rel="asset"><div><a href="">&#160;</a></div><label><a href=""></a></label></div>');
			thumb.find('a').attr('href', asset.url).click(MediaBrowser.selectAssetLink);
			thumb.find('label a').html(asset.filename);
			view.append(thumb);
		}

		for(var i in data.assets.files) {
			var asset = data.assets.files[i];
			var thumb = $('<div class="thumbnail file" rel="asset"><div><a href="">&#160;</a></div><label><a href=""></a></label></div>');
			thumb.find('a').attr('href', asset.url).click(MediaBrowser.selectAssetLink);
			thumb.find('label a').html(asset.filename);
			if(asset.filecategory=='image') {
				thumb.find('div a').html($('<img width="150" />').attr('src', asset.url));
			}
			view.append(thumb);
		}
	},

	/**
	* This handler is bound to the "click" event on all asset links in the view.
	*
	* @return bool
	*/
	selectAssetLink: function() {

		// Get info about the link
		var link = $(this);
		var url = link.attr('href')
		var assetType = link.parents('[rel*=asset]').hasClass('folder') ? 'folder' : 'file';

		// Folder: Load path into view
		if(assetType==='folder') {
			MediaBrowser.load(link.attr('href'));
		}

		// File
		else if(assetType==='file') {
			MediaBrowser.selectFile(url);
		}

		// Prevent bubbling
		return false;
	},

	/**
	* Adds the specified file to the list of selections.
	*
	* @param string URL to file
	* @return void
	*/
	selectFile: function(path) {
		MediaBrowser.config.data.push(path);
		if(MediaBrowser.config.data.length>MediaBrowser.config.smax) {
			MediaBrowser.config.data.shift();
		}
		MediaBrowser.renderSelection();
	},

	/**
	* Toggle the view layout.
	*
	* @param string Layout (list | thumbnails)
	* @return void
	*/
	toggleLayout: function(layout) {
		if(layout!==MediaBrowser.config.view) {
			MediaBrowser.config.view = layout;
			MediaBrowser.renderView(MediaBrowser.cache[MediaBrowser.config.path]);
		}
	}
}